package com.ruoyi.back.service.impl

import cn.hutool.core.bean.BeanUtil
import cn.hutool.core.date.DateUtil
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import com.ruoyi.app.common.PageData
import com.ruoyi.app.common.format
import com.ruoyi.app.common.format1
import com.ruoyi.app.common.pageInfo
import com.ruoyi.back.domain.UserRecord
import com.ruoyi.back.domain.vo.ResourceInfo
import com.ruoyi.back.domain.vo.ResourceInfos
import com.ruoyi.back.domain.vo.ResourceSearchDto
import com.ruoyi.back.mapper.RecordMapper
import com.ruoyi.back.service.AppUserService
import com.ruoyi.back.service.FunctionService
import com.ruoyi.back.service.UserRecordService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service

@Service
class UserRecordServiceImpl : ServiceImpl<RecordMapper, UserRecord>(), UserRecordService {

    @Autowired
    private lateinit var functionService: FunctionService

    @Autowired
    private lateinit var appUserService: AppUserService

    fun userChangeFaceNumCa(userId: Long): Pair<Int, Int> {
        appUserService.getById(userId).let { appUser ->
            val totalFaceNum = appUser.totalChangeFaceCount ?: 0
            //如果视频换脸次数 > 最大换脸次数 视频最大 图片0
            //如果视频换脸次数 < 最大换脸次数  视频正常 剩下的取图片

            val videoChangeFaceNum = count(
                KtQueryWrapper(UserRecord::class.java)
                    .eq(UserRecord::createBy, userId)
                    .eq(UserRecord::status, 2)
                    .eq(UserRecord::functionId, 1)
            )

            if (videoChangeFaceNum >= totalFaceNum) {
                return totalFaceNum to 0
            }

            return videoChangeFaceNum to totalFaceNum - videoChangeFaceNum
        }
    }


    override fun getUserChangeFaceNum(userId: Long, type: Int?): Long =
        functionService.getFaceId().let { pair ->
            when (type) {
                1 -> pair.first.run {
                    count(
                        KtQueryWrapper(UserRecord::class.java)
                            .eq(UserRecord::createBy, userId)
                            .eq(UserRecord::status,2 )
                            .eq(UserRecord::functionId, this)
                    ).run {
                        takeIf { it >= userChangeFaceNumCa(userId).first }
                            ?.run { userChangeFaceNumCa(userId).first }
                            ?: this
                    }
                }.toLong() + pair.second.run {
                    count(
                        KtQueryWrapper(UserRecord::class.java)
                            .eq(UserRecord::createBy, userId)
                            .eq(UserRecord::status,2 )
                            .eq(UserRecord::functionId, this)
                    ).run {
                        takeIf { it >= userChangeFaceNumCa(userId).second }
                            ?.run { userChangeFaceNumCa(userId).second }
                            ?: this
                    }
                }.toLong()

                2 -> pair.first.run {
                    count(
                        KtQueryWrapper(UserRecord::class.java)
                            .eq(UserRecord::createBy, userId)
                            .eq(UserRecord::status,2 )
                            .eq(UserRecord::functionId, this)
                    ).run {
                        takeIf { it >= userChangeFaceNumCa(userId).first }
                            ?.run { userChangeFaceNumCa(userId).first }
                            ?: this
                    }
                }.toLong()

                3 -> pair.second.run {
                    count(
                        KtQueryWrapper(UserRecord::class.java)
                            .eq(UserRecord::createBy, userId)
                            .eq(UserRecord::status,2 )
                            .eq(UserRecord::functionId, this)
                    ).run {
                        takeIf { it >= userChangeFaceNumCa(userId).second }
                            ?.run { userChangeFaceNumCa(userId).second }
                            ?: this
                    }
                }.toLong()

                else -> 0
            }
        }

    override fun getUserResourceRecordPage(resourceSearchDto: ResourceSearchDto): PageData<ResourceInfos> =
        functionService.getFaceId().let { pair ->
            page(Page(resourceSearchDto.pageDomain!!.pageNum.toLong(), resourceSearchDto.pageDomain!!.pageSize.toLong()),
                KtQueryWrapper(UserRecord::class.java).apply {

                    eq(UserRecord::createBy, resourceSearchDto.userId)
                    eq(
                        resourceSearchDto.changeFaceResult != null,
                        UserRecord::status,
                        if (resourceSearchDto.changeFaceResult == true) 2 else 1
                    )
                    eq(
                        resourceSearchDto.single != null,
                        UserRecord::singleChangeFace,
                        resourceSearchDto.single
                    )
                    eq(
                        resourceSearchDto.deleteTag != null,
                        UserRecord::deleteTag,
                        if (resourceSearchDto.deleteTag == true) 1 else 0
                    )
                    when (resourceSearchDto.param) {
                        //1 -> eq(UserRecord::functionId, pair.first).or().eq(UserRecord::functionId, pair.second)
                        2 -> eq(UserRecord::functionId, pair.first)
                        3 -> eq(UserRecord::functionId, pair.second)
                        else -> {}
                    }
                    orderByDesc(UserRecord::createTime)
                }).let { page: Page<UserRecord> ->
                Page<ResourceInfos>().apply {
                    BeanUtil.copyProperties(page, this)
                    records = page.records.takeIf { it.isNotEmpty() }?.run {
                        map {
                            ResourceInfo().apply {
                                recordId = it.id
                                requestId = it.requestId
                                status = it.status
                                uploadTime = it.createTime?.format()
                                completeTime = it.completeTime?.format()
                                completeTime?.run {
                                    useTime = DateUtil.formatBetween(it.createTime, it.completeTime)
                                }
                                useApi = if (it.apiType == 1) "阿里" else "火山"
                                usePoint = it.usePoint
                                deleteTag = it.deleteTag
                                deleteTime = it.deleteTime?.format()
                                failReason = it.errorMsg
                                url = it.url
                                single = it.singleChangeFace ?: false
                                type = if (pair.first == it.functionId) 1 else 2
                                time = it.createTime?.format1()

                            }
                        }.groupBy { it.time }
                            .map { (k, v) ->
                                ResourceInfos().apply {
                                    time = k
                                    resourceInfo = v
                                }
                            }
                    }
                }.pageInfo()
            }
        }
}